package com.bdsoft.actions.noticeManage.Service.impl;

import cn.hutool.core.collection.CollUtil;
import com.bdsoft.actions.noticeManage.DTO.NoticeDTO;
import com.bdsoft.actions.noticeManage.DAO.NoticeMapper;
import com.bdsoft.actions.noticeManage.Service.NoticeService;
import com.bdsoft.security.util.JwtUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class NoticeServiceImpl implements NoticeService {

    // 状态常量
    //DRAFT：草稿状态，值为0，表示内容处于未发布状态。
    private static final Integer DRAFT = 0;

    //PUBLISHED：已发布状态，值为1，表示内容已经对外公开。
    private static final Integer PUBLISHED = 1;

    //REVOKED：已撤销状态，值为2，表示内容已被管理员从对外公开的状态中移除。
    private static final Integer REVOKED = 2;

    @Autowired
    private NoticeMapper noticeMapper;

    /**
     * 获取通知列表的分页信息
     *
     * @param pageNum 当前页码
     * @param pageSize 每页记录数
     * @param title    通知标题（可选）
     * @param status   通知状态（可选）
     * @param authHeader 认证头信息
     * @return 分页信息对象，包含通知列表及分页信息
     */
    /**
     * 获取通知列表的分页信息
     */
    @Override
    public PageInfo<Map<String, Object>> getNoticeList(int pageNum, int pageSize, String title, Integer status ,String authHeader) {
        // 开启分页插件
        PageHelper.startPage(pageNum, pageSize);

        // 查询通知列表
        List<Map<String, Object>> notices = noticeMapper.selectNoticeList(title, status);

        // 将查询结果封装为PageInfo对象并返回
        return new PageInfo<>(notices);
    }



    /**
     * 创建公告
     */
    @Override
    public Map<String, Object> createNotice(NoticeDTO noticeDTO, String authHeader) {
        // 去掉"Bearer "前缀
        String token = authHeader.substring(7); // 去掉"Bearer "前缀
        // 从token中获取用户名
        String username = JwtUtil.getUsernameFromToken(token);
        // 从token中获取用户ID
        String userId = JwtUtil.getUserIdFromToken(token);

        // 检查ID是否已存在
        Map<String, Object> existingNotice = noticeMapper.selectNoticeById(noticeDTO.getId());
        if (existingNotice != null) {
            // ID已存在
            return Map.of(
                    "code", 400,
                    "message", "公告ID已存在",
                    "suggestion", "请使用不同的ID创建公告"
            );
        }

        // 设置公告状态为草稿
        noticeDTO.setStatus(DRAFT);
        // 设置公告创建时间
        noticeDTO.setCreateTime(new Date());
        // 设置公告更新时间
        noticeDTO.setUpdateTime(new Date());

        // 设置创建者ID
        noticeDTO.setCreatorId(userId);
        // 插入数据
        int result = noticeMapper.insertNotice(noticeDTO);
        if (result > 0) {
            // 创建成功，返回成功信息和公告数据
            return Map.of(
                    "code", 200,
                    "message", "公告创建成功",
                    "data", noticeMapper.selectNoticeById(noticeDTO.getId())
            );
        }
        // 创建失败，返回失败信息
        return Map.of("code", 500, "message", "公告创建失败");
    }



    /**
     * 保存或更新公告信息
     */
    @Override
    public Map<String, Object> saveOrUpdateNotice(NoticeDTO noticeDTO) {
        // 是否存在公告
        // 查询公告是否存在
        Map<String, Object> existingNotice = noticeMapper.selectNoticeById(noticeDTO.getId());
        if (existingNotice == null) {
            // 不存在
            return Map.of(
                    "code", 404,
                    "message", "公告ID不存在",
                    "details", String.format("无法更新，ID为[%s]的公告不存在", noticeDTO.getId()),
                    "suggestion", "请检查ID是否正确或先创建该公告"
            );
        }

        // 检查公告状态是否已发布
        if (PUBLISHED.equals(existingNotice.get("status"))) {
            // 已发布
            return Map.of(
                    "code", 400,
                    "message", "已发布的公告不允许修改",
                    "currentStatus", "PUBLISHED(1)",
                    "suggestion", "如需修改请先撤回公告"
            );
        }

        // 更新公告信息
        // 更新公告的时间戳
        noticeDTO.setUpdateTime(new Date());
        int result = noticeMapper.updateNotice(noticeDTO);

        if (result > 0) {
            // 更新成功
            return Map.of(
                    "code", 200,
                    "message", "公告更新成功",
                    "data", noticeMapper.selectNoticeById(noticeDTO.getId()),
                    "updatedFields", List.of("title", "content", "updateTime")
            );
        }
        // 如果更新失败
        return Map.of("code", 500, "message", "公告更新失败");
    }



    /**
     * 根据给定的ID删除公告
     */
    @Override
    public Map<String, Object> deleteNotice(String id) {
        // 根据ID查询公告
        Map<String, Object> notice = noticeMapper.selectNoticeById(id);
        if (notice == null) {
            // 如果公告不存在
            return Map.of("code", 404, "message", "指定ID的公告不存在");
        }

        // 检查公告状态
        Integer status = (Integer) notice.get("status");
        if (PUBLISHED.equals(status)) {
            // 公告已发布
            return Map.of(
                    "code", 400,
                    "message", "已发布的公告不允许删除",
                    "suggestion", "如需删除请先撤回公告"
            );
        }

        // 删除公告（允许删除草稿和已撤销的公告）
        int result = noticeMapper.deleteNotice(id);
        if (result > 0) {
            // 删除成功
            return Map.of("code", 200, "message", "公告删除成功", "deletedId", id);
        }
        // 删除失败
        return Map.of("code", 500, "message", "公告删除失败");
    }
    /**
     * 批量删除公告
     */
    @Override
    @Transactional
    public Map<String, Object> batchDeleteNotice(List<String> ids) {
        // 检查ID列表是否为空
        if (CollUtil.isEmpty(ids)) {
            return Map.of("code", 400, "message", "ID列表不能为空");
        }

        // 遍历ID列表，查询每个ID对应的公告信息
        List<Map<String, Object>> forbiddenNotices = ids.stream()
                .map(noticeMapper::selectNoticeById)
                // 过滤出已发布的公告（只禁止删除已发布状态，允许删除草稿和已撤销状态）
                .filter(notice -> notice != null && PUBLISHED.equals(notice.get("status")))
                .collect(Collectors.toList());

        // 如果存在不允许删除的公告
        if (CollUtil.isNotEmpty(forbiddenNotices)) {
            // 提取不允许删除的公告的ID列表
            List<String> forbiddenIds = forbiddenNotices.stream()
                    .map(notice -> (String) notice.get("id"))
                    .collect(Collectors.toList());
            // 返回错误信息
            return Map.of(
                    "code", 400,
                    "message", "包含已发布的公告，无法删除",
                    "forbiddenIds", forbiddenIds
            );
        }

        // 执行批量删除操作
        int result = noticeMapper.batchDeleteNotice(ids);
        if (result > 0) {
            // 删除成功
            return Map.of(
                    "code", 200,
                    "message", "批量删除成功",
                    "deletedCount", result
            );
        }

        // 删除失败
        return Map.of("code", 500, "message", "批量删除失败");
    }

    /**
     * 获取公告详情
     */
    @Override
    public Map<String, Object> getNoticeDetail(String id) {
        // 从数据库中查询公告详情
        Map<String, Object> notice = noticeMapper.selectNoticeById(id);
        // 判断公告是否存在
        if (notice == null) {
            // 公告不存在
            return Map.of("code", 404, "message", "公告不存在");
        }

        // 公告存在
        return Map.of("code", 200, "data", notice);
    }


    /**
     * 发布公告
     */
    @Override
    public Map<String, Object> publishNotice(String id) {
        // 通过ID查询公告
        Map<String, Object> notice = noticeMapper.selectNoticeById(id);
        if (notice == null) {
            // 公告不存在
            return Map.of("code", 404, "message", "公告不存在");
        }

        // 检查公告是否是草稿
        if (!DRAFT.equals(notice.get("status"))) {
            // 如果不是
            return Map.of(
                    "code", 400,
                    "message", "只有草稿状态的公告可以发布",
                    "currentStatus", notice.get("status")
            );
        }
        // 发布公告
        int result = noticeMapper.publishNotice(id);
        if (result > 0) {
            // 发布成功
            return Map.of(
                    "code", 200,
                    "message", "公告发布成功",
                    "data", noticeMapper.selectNoticeById(id)
            );
        }
        // 发布失败
        return Map.of("code", 500, "message", "公告发布失败");
    }


    /**
     * 撤回公告
     */
    @Override
    public Map<String, Object> revokeNotice(String id) {
        // 根据ID查询公告
        Map<String, Object> notice = noticeMapper.selectNoticeById(id);
        if (notice == null) {
            // 公告不存在
            return Map.of("code", 404, "message", "公告不存在");
        }

        // 检查公告的状态是否为已发布
        if (!PUBLISHED.equals(notice.get("status"))) {
            // 公告未发布，无法撤回
            return Map.of(
                    "code", 400,
                    "message", "只有已发布的公告可以撤回",
                    "currentStatus", notice.get("status")
            );
        }
        // 撤回公告
        int result = noticeMapper.revokeNotice(id);
        if (result > 0) {
            // 撤回成功，返回撤回后的公告信息
            return Map.of(
                    "code", 200,
                    "message", "公告撤回成功",
                    "data", noticeMapper.selectNoticeById(id)
            );
        }
        // 撤回失败
        return Map.of("code", 500, "message", "公告撤回失败");
    }

}